<template>
  <div class="password-input-wrapper">
    <div class="input-container">
      <input
          :type="passwordType"
          :value="modelValue"
          :placeholder="placeholder"
          :disabled="disabled"
          :readonly="readonly"
          :maxlength="maxlength"
          :class="computedClass"
          :style="style"
          :pattern="pattern"
          @input="handleInput"
          @change="handleChange"
          @focus="handleFocus"
          @blur="handleBlur"
          @keydown="handleKeydown"
          @keyup="handleKeyup"
          aria-label="Password input"
          :aria-invalid="!!errorMessage"
      />
      <button
          v-if="toggleable"
          type="button"
          class="toggle-button"
          @click="togglePasswordVisibility"
          aria-label="Toggle password visibility"
      >
        {{ showPasswordIcon }}
      </button>
    </div>

    <div v-if="strengthMeter" class="strength-meter">
      <div
          class="strength-bar"
          :class="strengthClass"
          :style="{ width: strengthWidth }"
      ></div>
      <span class="strength-text">{{ strengthText }}</span>
    </div>

    <div v-if="errorMessage" class="message error">
      {{ errorMessage }}
    </div>
    <div v-else-if="successMessage" class="message success">
      {{ successMessage }}
    </div>
  </div>
</template>

<script setup>
import { computed, ref } from 'vue'

const props = defineProps({
  modelValue: String,
  placeholder: String,
  disabled: Boolean,
  readonly: Boolean,
  maxlength: Number,
  showPassword: Boolean,
  toggleable: Boolean,
  strengthMeter: Boolean,
  pattern: String,
  class: [String, Array, Object],
  style: [String, Object],
  errorMessage: String,
  successMessage: String
})

const emit = defineEmits([
  'update:modelValue',
  'input',
  'change',
  'focus',
  'blur',
  'keydown',
  'keyup',
  'toggleShowPassword'
])

const localShowPassword = ref(props.showPassword)

const passwordType = computed(() =>
    localShowPassword.value ? 'text' : 'password'
)

const showPasswordIcon = computed(() =>
    localShowPassword.value ? '👁️' : '👁️🗨️'
)

const handleInput = (e) => {
  emit('update:modelValue', e.target.value)
  emit('input', e)
}

const handleChange = (e) => {
  emit('change', e)
}

const handleFocus = (e) => {
  emit('focus', e)
}

const handleBlur = (e) => {
  emit('blur', e)
}

const handleKeydown = (e) => {
  emit('keydown', e)
}

const handleKeyup = (e) => {
  emit('keyup', e)
}

const togglePasswordVisibility = () => {
  localShowPassword.value = !localShowPassword.value
  emit('toggleShowPassword', localShowPassword.value)
}

const computedClass = computed(() => [
  props.class,
  'password-input',
  {
    'is-invalid': props.errorMessage,
    'is-valid': props.successMessage,
    'disabled': props.disabled
  }
])

// 密码强度计算
const strengthLevel = computed(() => {
  const password = props.modelValue || ''
  let strength = 0

  // 长度评分
  if (password.length >= 8) strength += 1
  if (password.length >= 12) strength += 1

  // 字符类型评分
  const hasLower = /[a-z]/.test(password)
  const hasUpper = /[A-Z]/.test(password)
  const hasNumber = /\d/.test(password)
  const hasSpecial = /[^A-Za-z0-9]/.test(password)

  const typeCount = [hasLower, hasUpper, hasNumber, hasSpecial].filter(Boolean).length
  strength += typeCount

  if (strength <= 2) return 0 // 弱
  if (strength <= 4) return 1 // 中
  if (strength <= 6) return 2 // 强
  return 3 // 非常强
})

const strengthText = computed(() => {
  const levels = ['Weak', 'Medium', 'Strong', 'Very Strong']
  return levels[strengthLevel.value]
})

const strengthClass = computed(() => `strength-${strengthLevel.value}`)

const strengthWidth = computed(() =>
    `${(strengthLevel.value + 1) * 25}%`
)
</script>

<style scoped>
.password-input-wrapper {
  width: 100%;
  max-width: 400px;
}

.input-container {
  position: relative;
}

.password-input {
  width: 100%;
  padding: 8px 40px 8px 12px;
  border: 1px solid #ccc;
  border-radius: 4px;
  font-size: 16px;
}

.password-input:focus {
  outline: none;
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

.is-invalid {
  border-color: #f56c6c;
}

.is-valid {
  border-color: #67c23a;
}

.toggle-button {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
}

.strength-meter {
  margin-top: 8px;
  height: 4px;
  background: #eee;
  border-radius: 2px;
  overflow: hidden;
}

.strength-bar {
  height: 100%;
  transition: all 0.3s;
}

.strength-0 { background: #f56c6c; }
.strength-1 { background: #e6a23c; }
.strength-2 { background: #67c23a; }
.strength-3 { background: #409eff; }

.strength-text {
  display: block;
  font-size: 12px;
  color: #666;
  margin-top: 4px;
}

.message {
  font-size: 12px;
  margin-top: 4px;
}

.error { color: #f56c6c; }
.success { color: #67c23a; }

.disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
</style>